home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swagn_r.zip / NUMBERS.SWG / 0009_BYTEINFO.PAS.pas < prev    next >
Pascal/Delphi Source File  |  1993-05-28  |  7KB  |  266 lines

  1. {
  2. >Also, how would I simply read each bit?
  3. }
  4. { Test if a bit is set. }
  5. Function IsBitSet(Var INByte : Byte; Bit2Test : Byte) : Boolean;
  6. begin
  7.   if (Bit2Test in [0..7]) then
  8.     IsBitSet := ((INByte and (1 shl Bit2Test)) <> 0)
  9.   else
  10.     Writeln('ERROR! Bit to check is out of range!');
  11. end; { IsBitSet. }
  12.  
  13. {
  14. >How on earth can I manipulate an individual bit?
  15.  
  16. ...One method is to use the bit-operators:  AND, OR, XOR, NOT
  17. }
  18.  
  19. { Manipulate an individual BIT within a single Byte. }
  20. Procedure SetBit(Bit2Change : Byte; TurnOn : Boolean; Var INByte : Byte);
  21. begin
  22.   if Bit2Change in [0..7] then
  23.   begin
  24.     if TurnOn then
  25.       INByte := INByte or (1 shl Bit2Change)
  26.     else
  27.       INByte := INByte and NOT(1 shl Bit2Change);
  28.   end;
  29. end; { SetBit. }
  30.  
  31. {
  32. >...but I'm not sure exactly what the shifting is doing.
  33. }
  34.  
  35.     { Check if the bit is to be turned on or off. }
  36.     If TurnOn then
  37.  
  38.     {
  39.       SHL 1 (which has a bit map of 0000 0001) to the bit
  40.       position we want to turn-on.
  41.  
  42.         ie: 1 SHL 4 = bit-map of 0001 0000
  43.  
  44.       ...Then use a "logical OR" to set this bit.
  45.  
  46.       ie: Decimal:     2      or      16     =    18
  47.           Binary : 0000 0010  or  0001 0000  = 0001 0010
  48.     }
  49.  
  50.       INByte := INByte or (1 shl Bit2Change)
  51.     else
  52.  
  53.     {
  54.       Else turn-off bit.
  55.  
  56.       SHL 1 (which has a bit map of 0000 0001) to the bit
  57.       position we want to turn-off.
  58.  
  59.          ie: 1 SHL 4 = bit-map of 0001 0000
  60.  
  61.        ...Then use a "logical NOT" to flip all the bits.
  62.  
  63.        ie: Decimal:  not (   16    ) =      239
  64.            Binary :  not (0001 0000) =  (1110 1111)
  65.  
  66.        ...Than use a "logical AND" to turn-off the bit.
  67.  
  68.        ie: Decimal:     255     and     239    = 239
  69.            Binary :  1111 1111  and  1110 1111 = 1110 1111
  70.     }
  71.  
  72.      INByte := INByte and NOT(1 shl Bit2Change);
  73.  
  74. {
  75. >Also, how can you assign a Byte (InByte) a Boolean value (OR/AND/NOT)
  76.  
  77.   or / xor / and / not are "logical" bit operators, that can be use on
  78.   "scalar" Types. (They also Function in the same manner For "Boolean"
  79.   logic.)
  80.  
  81. >If I have, say 16 bits in one Byte, the interrupt list says that for
  82. >instance the BIOS calls (INT 11), AX is returned With the values. It
  83. >says that the bits from 9-11 tell how many serial portss there are.
  84. >How do I read 3 bits?
  85.  
  86.   To modify the two routines I posted wo work With 16 bit Variables,
  87.   you'll need to change:
  88.  
  89.      INByte : Byte;  --->  INWord : Word;
  90.  
  91.   ...Also:
  92.  
  93.      in [0..7]  --->  in [0..15]
  94.  
  95.   ...If you don't want to use the IsBitSet Function listed above
  96.   (modified to accept 16-bit Word values) you could do the following
  97.   to check if bits  9, 10, 11 are set in a 16-bit value:
  98.  
  99.   The following is the correct code For reading bits 9, 10, 11
  100.   of the 16-bit Variable "AX_Value" :
  101.  
  102.       Port_Count :=  ((AX_Value and $E00) SHR 9);
  103.  
  104.     NOTE: Bit-map For $E00 = 0000 1110 0000 0000
  105.  
  106.   ...If you've got a copy of Tom Swan's "Mastering Turbo Pascal",
  107.   check the section on "logical operators".
  108.  
  109.  
  110. {
  111. >Var Regs : Registers;
  112. >begin
  113. >  Intr($11,Regs);
  114. >  Writeln(Regs.AX);
  115. >end.
  116.  
  117. >How do I manipulate that to read each bit (or multiple bits like
  118. >the number of serial ports installed (bits 9-11) ?
  119. }
  120.  
  121. Uses
  122.   Dos;
  123.  
  124. Var
  125.   Port_Count : Byte;
  126.   Regs       : Registers;
  127.  
  128. begin
  129.   Intr($11, Regs);
  130.   Port_Count := ((Regs.AX and $E00) SHR 9);
  131.   Writeln('Number of serial-ports = ', Port_Count)
  132. end.
  133. {
  134. NOTE: The hex value of $E00 is equivalent to a 16-bit value with
  135.       only bits 9, 10, 11 set to a binary 1. The SHR 9 shifts the
  136.       top Byte of the 16-bit value, to the lower Byte position.
  137. }
  138. {
  139. >Is $E00 the same as $0E00 (ie, can you just omit leading zeros)?
  140.  
  141. Yeah, it's up to you if you want to use the leading zeros or not.
  142.  
  143. The SHR 9 comes in because once the value has been "AND'd" with
  144. $E00, the 3 bits (9, 10, 11) must be placed at bit positions:
  145. 0, 1, 2  ...to correctly read their value.
  146.  
  147. For example, say bits 9 and 11 were set, but not bit 10. If we
  148. "AND" this With $E00, the result is $A00.
  149.  
  150. 1011 1010 0111 1110  and  0000 1110 0000 0000  =  0000 1010 0000 0000
  151.        ^ ^
  152. (bits 9,11 are set)  and  (      $E00       )  =  $A00
  153. ...Taking the result of $A00, and shifting it right 9 bit positions
  154.  
  155.          $A00         SHR 9  =           5
  156.  
  157.  0000 1010 0000 0000  SHR 9  =  0000 0000 0000 0101
  158.  
  159. ...Which evalutates to 5. (ie: 5 serial ports)
  160. }
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168.  
  169.  
  170. {
  171. Get Equipment Bit-Map
  172. ---------------------
  173.  
  174.          AH       AL
  175.       76543210 76543210
  176. AX =  ppxgrrrx ffvvmmci
  177.  
  178. ...
  179. ...
  180. rrr = # of RS232 ports installed
  181. ...
  182. ...
  183.  
  184.  (* reports the number of RS232 ports installed *)
  185. Function NumRS232 : Byte;
  186. Var Regs : Registers;                 (* Uses Dos *)
  187. begin
  188.   Intr($11,Regs);
  189.   NumRS232 := (AH and $0E) shr 1;
  190. end;
  191.  
  192.  
  193. ...When you call Int $11, it will return the number of RS232 ports installed
  194. in bits 1-3 in register AH.
  195.  
  196. For example if AH = 01001110 , you can mask out the bits you *don't* want
  197. by using AND, like this:
  198.  
  199.               01001110      <---  AH
  200.         and   00001110      <---- mask $0E
  201.         ──────────────
  202.               00001110      <---- after masking
  203.  
  204.  
  205. Then shift the bits to the right With SHR,
  206.  
  207.               00001110      <---- after masking
  208.          SHR         1      <---- shift-right one bit position
  209.          ─────────────
  210.               00000111      <---- result you want
  211. }
  212.  
  213. {
  214. -> How do I know to use $4 For the third bit?  Suppose I want to read
  215. -> the fifth bit. Do I simply use b := b or $6?
  216.  
  217.     Binary is a number system just like decimal.  Let me explain.
  218. First, consider the number "123" in decimal.  What this means,
  219. literally, is
  220.  
  221. 1*(10^2) + 2*(10^1) + 3*(10^0), which is 100 + 20 + 3.
  222.  
  223.     Binary works just the same, however instead of a 10, a 2 is used as
  224. the base.  So the number "1011" means
  225.  
  226. 1*(2^3) + 0*(2^2) + 1*(2^1) + 1*(2^0), or 8+0+2+1, or 11.
  227.  
  228.      This should make it clear why if you wish to set the nth bit to
  229. True, you simply use a number equal to 2^(n-1).  (The -1 is there
  230. because you probably count from 1, whereas the powers of two, as you may
  231. note, start at 0.)
  232.  
  233. -> b or (1 SHL 2) Would mean that b := 1 (True) if b is already equal to
  234. -> one (1) and/OR the bit two (2) to the left is one (1) ???
  235.  
  236.     Aha.  You are not familiar With bitwise or operations.  When one
  237. attempts to or two non-Boolean values (Integers), instead of doing a
  238. logical or as you are familiar with, each individual BIT is or'd.  I.E.
  239. imagine a Variables A and B had the following values:
  240.  
  241. a := 1100 (binary);
  242. b := 1010 (binary);
  243.  
  244. then, a or b would be equal to 1110 (binary);  Notice that each bit of a
  245. has been or'd With the corresponding bit of b?  The same goes For and.
  246. Here's an example.
  247.  
  248. a := 1100 (binary);
  249. b := 1010 (binary);
  250.  
  251. a and b would be equal to 1000;
  252.  
  253. I hope this clears up the confusion.  And just to be sure, I'm going to
  254. briefly show a SHL and SHR operation to make sure you know.  Consider
  255. the number
  256.  
  257. a := 10100 (binary);
  258.  
  259. This being the number, A SHL 2 would be equal to 1010000 (binary) --
  260. notice that it has been "shifted to the left" by 2 bits.
  261.  
  262. A SHR 1 would be 1010 (binary), which is a shifted to the right by 2
  263. bits.
  264. }
  265.  
  266.